package com.my.ext.service.impl;

import java.util.Base64;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.my.ext.entity.Contribution;
import com.my.ext.entity.Group;
import com.my.ext.entity.Node;
import com.my.ext.entity.User;
import com.my.ext.mapper.ContributionMapper;
import com.my.ext.mapper.GroupMapper;
import com.my.ext.mapper.NodeMapper;
import com.my.ext.mapper.UserMapper;
import com.my.ext.service.IMapService;
import com.my.ext.utils.AESCoder;
import com.my.ext.utils.ResultObject;
import com.my.ext.utils.StaticUtils;

@Service
public class MapService implements IMapService{
	
	@Autowired
	UserMapper mapper;
	
	@Autowired
	NodeMapper nodeMapper;
	
	@Autowired 
	GroupMapper groupMapper;
	
	@Autowired
	ContributionMapper contributionMapper;
	
	
	
	public ResultObject queryMyMap(String openid) {
		ResultObject obj = new ResultObject();
		obj.setStatus(1);
		User u = mapper.findUser(openid);
		List<Node> list = nodeMapper.queryAllNode();
		List<Group> groupList =  groupMapper.findAll(u.getOrg());
		for(Group g : groupList) {
			if(g.getId() == u.getGroup().getId()) {
				g.setSelf(true);
			}
			modifyGroup(g, false);
		}
		Contribution c = contributionMapper.queryMTContribution(u.getId(), StaticUtils.convertToday());
		int myToday = 0;
		if(c != null) {
			myToday = c.getContr();
		}
		int myTotle = contributionMapper.myCount(u.getId());
		Map<String , Object> map = new HashedMap();
		map.put("userinfo", u);
		map.put("nodes", list);
		map.put("group", groupList);
		map.put("myToday", myToday);
		map.put("myTotle", myTotle);
		obj.setData(map);
		return obj;
	}



	@Override
	public ResultObject go(int org, int groupid, String openid, int userid, int contr) {
		User u = mapper.findUser(openid);
		Group g = groupMapper.findMy(openid);
		Contribution c = contributionMapper.queryMTContribution(u.getId(), StaticUtils.convertToday());
		if(c == null) {
			contributionMapper.saveCont(u.getId(), contr, StaticUtils.convertToday(), g.getId());
		} else {
			contributionMapper.updateCont(u.getId(), StaticUtils.convertToday(), contr);
		}
		c = contributionMapper.queryMTContribution(u.getId(), StaticUtils.convertToday());
		modifyGroup(g, true);
		Map<String, Object> map = new HashedMap();
		map.put("user", u);
		map.put("group", g);
		map.put("today_contr", c.getContr());
		map.put("my_contri", contributionMapper.myCount(u.getId()));
		u.setGroup(g);
		ResultObject obj = new ResultObject();
		obj.setStatus(1);
		obj.setData(map);
		return obj;
	}
	
	private void modifyGroup(Group g, boolean isUpdate) {
		List<Contribution> list = contributionMapper.findById(g.getId());
		int steps = 0;
		for(Contribution c : list) {
			steps = steps + c.getContr();
		}
		g.setSelf(true);
		List<Node> nodes = nodeMapper.queryAllNode();
		int nodeIndex = 0;
		for(int i = 0; i<nodes.size(); i++) {
			if(nodes.get(i).getId() == g.getNode().getId()) {
				nodeIndex = i;
				break;
			}
		}
		if(steps > nodes.get(nodeIndex).getValue()) {
			g.setLatitude(nodes.get(nodeIndex).getLatitude());
			g.setLongitude(nodes.get(nodeIndex).getLongitude());
			g.setStatus(1);
		} else {
			double rate = (double) (steps-nodes.get(nodeIndex-1).getValue())/(nodes.get(nodeIndex).getValue() - nodes.get(nodeIndex-1).getValue());
			double la = rate * (nodes.get(nodeIndex).getLatitude() - nodes.get(nodeIndex-1).getLatitude()) +nodes.get(nodeIndex-1).getLatitude();
			double lo = rate * (nodes.get(nodeIndex).getLongitude() - nodes.get(nodeIndex-1).getLongitude()) +nodes.get(nodeIndex-1).getLongitude();
			g.setLongitude(lo);
			g.setLatitude(la);
		}
		if(isUpdate) {			
			groupMapper.updateGroup(g);
		}
	}



	@Override
	public ResultObject decode(String data, String iv, String openid) {
		byte[] edata = Base64.getDecoder().decode(data.getBytes());
		String session_key = mapper.getSessionKey(openid);
		byte[] aeskey = Base64.getDecoder().decode(session_key.getBytes());
		byte[] ivs = Base64.getDecoder().decode(iv.getBytes());
		String str = AESCoder.AESCBCUtil.decrypt(data, ivs,aeskey);
		ResultObject obj = new ResultObject();
		obj.setStatus(1);
		obj.setData(str);
		System.out.println(obj);
		return obj;
	}
}

















